---@class Battle.PoolMgr
local PoolMgr = Battle.CreateClass("PoolMgr")
Battle.PoolMgr = PoolMgr
local this = PoolMgr
function PoolMgr.OnCreate()
    this.cacheDataList = {}
    ---@type table<number,Battle.StateBase[]>
    this.cacheStateList = {}        --状态缓存
    ---@type table<number,Battle.AiBase[]>
    this.cacheAiList = {}       --ai缓存
    ---@type table<string,GameObject[]>
    this.resObjList = {}        --资源缓存
    this.resObjRequestList = {} --资源加载回调
    ---@type table<number,Battle.EffectBase[]>
    this.cacheEffectList = {} --特效缓存
    ---@type Battle.Bullet[]
    this.cacheBulletList = {}   --buff缓存
    ---@type Battle.Buffer[]
    this.cacheBufferList = {}   --buff缓存
    this.staticId = 0
end
function PoolMgr.OnDestroy()
    if this.resObjList then
        for k,v in pairs(this.resObjList) do
            for k2,v2 in pairs(v) do
                resMgr:ReleaseInstantiate(v2)
            end
        end
    end
    this.cacheDataList = nil
    this.cacheStateList = nil
    this.cacheAiList = nil
    this.resObjList = nil
    this.resObjRequestList = nil
end
--region state
function PoolMgr.GetStateFromPool(stateId)
    local list = this.cacheStateList[stateId]
    if list and #list > 0 then
        return table.remove(list)
    end
    local state = Battle.ActionStateMapping[stateId]
    if not state then
        logError("未注册该状态 "..stateId)
        return nil
    end
    return state.New(stateId)
end
---@param state Battle.StateBase
function PoolMgr.ReturnStateToPool(state)
    local tb = this.cacheStateList[state.stateId] or {}
    table.insert(tb,state)
    this.cacheStateList[state.stateId] = tb
end
--endregion state
--region stateData
function PoolMgr.GetStateDataFromPool()
    local tb
    if #this.cacheDataList > 0 then
        tb = table.remove(this.cacheDataList)
    else
        tb = {}
    end
    return tb
end
function PoolMgr.ReturnStateDataToPool(tb)
    if tb == nil then return end
    if type(tb) == "table" then
        table.clear(tb)
        table.insert(this.cacheDataList,tb)
    end
end
--endregion stateData
--region AiBase
---@param aiType Battle.AiType
function PoolMgr.GetAiFromPool(aiType)
    local list = this.cacheAiList[aiType.id]
    if list and #list > 0 then
        return table.remove(list)
    end
    local ai = aiType.clazz
    if not ai then
        logError("未注册该ai "..aiType.id)
        return nil
    end
    return ai.New(aiType.id)
end
---@param ai Battle.AiBase
function PoolMgr.ReturnAiToPool(ai)
    if ai == nil then return end
    local _list = this.cacheAiList[ai.aiType]
    if not _list then
        _list = {}
        this.cacheAiList[ai.aiType] = _list
    end
    table.insert(_list,ai)
end
--endregion AiBase
--region resObj
---@private
function PoolMgr.GetUniqueId()
    this.staticId = this.staticId + 1
    return this.staticId
end
function PoolMgr.LoadPrefabFromPool(path,callback,tb,param)
    local obj = this.GetPrefabFromPool(path)
    if obj then
        if callback then
            callback(tb,obj,param)
        end
        return 0
    end
    local id = this.LoadPrefab(path,callback,tb,param)
    return id
end
function PoolMgr.GetPrefabFromPool(path)
    local _list = this.resObjList[path]
    if _list and #_list > 0 then
        local obj = table.remove(_list)
        obj:SetActive(true)
        return obj
    end
    return nil
end
---@param obj GameObject
function PoolMgr.ReturnPrefabToPool(path,obj,active)
    if path == "" or not obj then return end
    Battle.SceneMgr.AddPoolChild(obj.transform)
    obj:SetActive(active or false)
    local _list = this.resObjList[path]
    if not _list then
        _list = {}
        this.resObjList[path] = _list
    end
    table.insert(_list,obj)
end
---@private
function PoolMgr.LoadCallback(data,obj)
    data.callback(data.tb,obj,data.param)
    if data.id then
        this.resObjRequestList[data.id] = nil
    end
end
---@private
function PoolMgr.LoadPrefab(path,callback,tb,param)
    local _table = {}
    _table.callback = callback
    _table.tb = tb
    _table.param = param
    _table.path = path
    _table.id = 0
    local obj = resMgr:Instantiate(path)
    callback(tb,obj,param)
    --local id = resMgr:InstantiateAsync(path,function(obj1)
    --   this.LoadCallback(_table,obj1)
    --end)
    --_table.id = id
    --this.resObjRequestList[id] = _table
    return 0
end
function PoolMgr.CancelLoad(requestId)
    if requestId == nil then return end
    if this.resObjRequestList[requestId] then
        resMgr:ReleaseInstantiate(requestId)
    end
    this.resObjRequestList[requestId] = nil
end
--endregion resObj
--region effectBase
---@return Battle.EffectBase
function PoolMgr.GetEffectFromPool(_type)
    local _list = this.cacheEffectList[_type]
    if _list and #_list > 0 then
        local eff = table.remove(_list)
        return eff
    end
    local eff = Battle.EffectMapping[_type]
    if not eff then
        logError("未注册该Effect ".._type)
        return nil
    end
    local e =  eff.New(_type)
    return e
end
---@param effect Battle.EffectBase
function PoolMgr.ReturnEffectToPool(effect)
    if effect == nil then return end
    if effect.effectType == nil then
        logError(effect.__cname.." 特效类型不明确，无法入池")
        return
    end
    local _list = this.cacheEffectList[effect.effectType]
    if not _list then
        _list = {}
        this.cacheEffectList[effect.effectType] = _list
    end
    for k,v in pairs(_list) do
        if v == effect then
            return
        end
    end
    table.insert(_list,effect)
end

--endregion effectBase
--region bullet
---@return Battle.Bullet
function PoolMgr.GetBulletFromPool()
    local _list = this.cacheBulletList
    if _list and #_list > 0 then
        local b = table.remove(_list)
        return b
    end
    return Battle.Bullet.New()
end
---@param bullet Battle.Bullet
function PoolMgr.ReturnBulletToPool(bullet)
    if bullet == nil then return end
    table.insert(this.cacheBulletList,bullet)
end
--endregion bullet

--endregion effectBase
--region Buffer
---@return Battle.Buffer
function PoolMgr.GetBufferFromPool()
    local _list = this.cacheBufferList
    if _list and #_list > 0 then
        local b = table.remove(_list)
        return b
    end
    return Battle.Buffer.New()
end
---@param buffer Battle.Buffer
function PoolMgr.ReturnBufferToPool(buffer)
    if buffer == nil then return end
    table.insert(this.cacheBufferList,buffer)
end
--endregion Buffer